package dviz.visualAspect;

import java.util.*;

import javassist.ClassPool;
import javassist.Translator;
import javassist.tools.reflect.Loader;

/**
 * @author  zxq071000
 */
public abstract class VisualizedClassLoader extends Loader {

	static final String HANDLER_CLASS = "dviz.visualAspect.FunctionInvokeHandler";
	static final String HELPER_CLASS = "dviz.visualAspect.AnnotationHelper";
	static final String FUNCTION_ANNOTATION = "dviz.visualAnnotation.FunctionMap";
	static final String CONSTRUCTOR_ANNOTATION = "dviz.visualAnnotation.ConstructMap";
	static final String OBJECT_ANNOTATION = "dviz.visualAnnotation.ObjectMap";
	static final String PARAMETER_ANNOTATION = "dviz.visualAnnotation.Param";
	static final String PROPERTY_ANNOTATION = "dviz.visualAnnotation.PropertyMap";
	static final String INVOKATION_CLASS = "dviz.visualAspect.Invokation";
	static final String INDEXOBJECT_INTERFACE = "dviz.visualAspect.IndexObject";
	static final String[] SAFE_PACKAGE = { "dviz.visualAspect.",
			"dviz.visualSystem.", "dviz.visualAnnotation.", "java.", "javax." };
	/**
	 * @uml.property  name="functionInvokeHandler"
	 * @uml.associationEnd  
	 */
	FunctionInvokeHandler functionInvokeHandler;
	ClassPool classPool;

	public static final HashMap<Object, FunctionInvokeHandler> handlers = new HashMap<Object, FunctionInvokeHandler>();
	// private static MessageDigest hashFunction;
	private static int UID_NEXT = 0;
	protected int UID;

	// static {
	// try {
	// hashFunction = MessageDigest.getInstance("MD5");
	// } catch (NoSuchAlgorithmException e) {
	// e.printStackTrace();
	// System.exit(0);
	// }
	// }

	/**
	 * @uml.property  name="clazzProperty"
	 */
	public HashMap<String, HashMap<String, MetaPropertyMap>> clazzPropertyMap;

	public static FunctionInvokeHandler getHandlerByLoader(Object loader) {

		return handlers.get(loader);
	}

	// public static VisualizedClassLoader createClassLoader(
	// FunctionInvokeHandler functionInvokeHandler) {
	//
	// try {
	// // VisualizedClassLoader classLoader = new VisualizedClassLoader(
	// // functionInvokeHandler);
	// VisualizedClassLoader classLoader = new AnnotationClassLoader(
	// functionInvokeHandler);
	//						
	// return classLoader;
	// } catch (Exception e) {
	// e.printStackTrace();
	// }
	// return null;
	// }

	public abstract Translator getTranslator();

	public VisualizedClassLoader(FunctionInvokeHandler functionInvokeHandler)
			throws Exception {
		super();
		UID = UID_NEXT++;
		handlers.put(UID, functionInvokeHandler);
		clazzPropertyMap = new HashMap<String, HashMap<String, MetaPropertyMap>>();

		for (String safe : SAFE_PACKAGE) {
			delegateLoadingOf(safe);
		}

		classPool = ClassPool.getDefault();
		this.functionInvokeHandler = functionInvokeHandler;

		// This translator will add intercept code before or after invocation of
		// method tagged with FunctionMap annotation
		this.addTranslator(classPool, getTranslator());
	}

	/**
	 * @return
	 * @uml.property  name="clazzProperty"
	 */
	public HashMap<String, HashMap<String, MetaPropertyMap>> getClazzPropertyMap() {
		return clazzPropertyMap;
	}
}
